package hybrid;

import java.util.List;

import pso.FitnessFunction;
import rbfnn.Training;

public class MyFitnessFunction extends FitnessFunction {
	//-------------------------------------------------------------------------
	// Methods
	//-------------------------------------------------------------------------
	public List<Training> Trainings;
	public double B; // Scaling Factor
	public int m; // Fuzziness Parameters
	
	public MyFitnessFunction(List<Training> _Trainings, double _B, int _m)
	{
		this.Trainings = _Trainings;
		this.B = _B;
		this.m = _m;
	}
	
	public double evaluate(double position[]) {  // Look Equation (13)
		// position.length is dimension of a particle
		int c = 0;
		double Sum = 0.0;  
	    double Sum2 = 0.0;  // for calculate (Euclidean distance between input and input centers ||xk - vi||^2) + Euclidean distance between output and output centers ||yk - ui||^2
		double Sum3 = 0.0;  // for calculate Euclidean distance between input and input centers ||xk - vi||
		for(int k = 0; k < Trainings.size(); k++)
		{
				for(int i = 0; i < position.length; i++) // Count Euclidean distance between input and input centers ||xk - vi||
				{
					if( (i + 1) % (this.Trainings.get(0).Inputs.size() + 1) != 0){ // if index modulo input size not equal zero, calculate euclidean distance for input and input center
						Sum3 = Sum3 + Math.pow(Trainings.get(k).Inputs.get(c) - position[i], 2);
						//System.out.println(" (" + Trainings.get(k).Inputs.get(c) + " - " + position[i] + ") ^ 2 = " + Math.pow(Trainings.get(k).Inputs.get(c) - position[i], 2));
						c++;
					}
					else {// else calculate euclidean distance between output and output center. This remark that move to the next cluster
						Sum2 = Sum2 + Math.pow(Sum3 + B * Math.pow(Trainings.get(k).Output - position[i], 2), 1 / (1 - this.m));
						//System.out.println(Sum3 + " + " + B + "*(" + Trainings.get(k).Output + " - " + position[i] + ") ^ 2 = " + Math.pow(Trainings.get(k).Output - position[i], 2));
						Sum3 = 0.0;
						c = 0;
					}
				}
			Sum = Sum + Math.pow(Sum2, 1 - m);
			Sum2 = 0.0;
			//System.out.println("Sum Input " + k + " = " + Sum);
			//System.out.println();
			//c = 0;
		}
		//System.out.println(position.length);
		return Sum;
	}

}
